<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div>打开控制台查看结果</div>
    <script>
        console.log('=========含义==========');
        /* 
           async函数是什么？一句话，它就是Generator函数的语法糖
           async对Generator的改进，体现在以下四点：
           1、内置执行器:async自带执行器，也就是说async的执行与普通函数一模一样，只要一行，而Generator则需要执行器才能执行。

           2、更好的语义：async和await比星号和yield，语义更清楚。async表示函数里有异步操作，await表示紧跟在后面的表达式需要等待结果。

           3、更广的适用性：oc模块约定，yield命令后面只能是Thunk函数或Promise对象，而async函数的await命令后面，可以使Promise对象和原始类型的值（数字、字符串和布尔值，但这时会自动转成立即resolved的Promise对象）

           4、返回的值是Promise：async函数返回值是Promise对象，这比Generator函数的返回值是Iterator对象方便多了。你可以用then方法指定下一步的操作。

           async函是完全可以看做多个异步操作，包装成的一个Promise对象，而await命令就是内部的then命令的语法糖。
        */

        console.log('============基本用法===========');
        /* async函数返回一个Promise对象，可以使用then方法添加回调函数。当函数执行的时候，一单遇到await就会先返回，等到异步操作完成，再接着执行函数体内后面的语句。 */
        function a(){
            console.log('a内的输出');
            return 5
        }
        function b(x){
            console.log('b内的输出');
            return x * 10
        }
        async function s(){
            console.log('同步操作');
            let num = await a()  // a()的返回值值是5，其实用原始类型也可以
            // let num = await 5
            console.log('同步操作2',num);
            let sum = await b(num)
            console.log('同步操作3',sum);
            return sum
        }
        s().then(el=>console.log(el))  // 50
        /* 
            同步操作
            a内的输出
            同步操作2 5
            b内的输出
            同步操作3 50
            50
        */
       /* 虽然async返回的是Promise对象，但函数执行时遇到await就会先返回，直到当前行的await执行完成，再接着执行后面的语句，所以这里不管是同步还是异步，遇到await都会等待执行，等await执行完成才会进行下一步执行。
          await返回的返回值为await右侧的函数或者原始类型的返回值。
          async返回的是Promise，所以可以使用then方法获取返回值。
       */

       
       /* async函数有多种使用形式 */
        /* 函数声明 */
        async function foo() {}

        /* 函数表达式 */
        const foo = async function() {}

        /* 对象的方法 */
        let obj = { async foo() {} }

        /* Class的方法 */
        class Storage {
            constructor() {
                this.cachePromise = caches.open('avatars')
            }

            async getAvatat(name) {
                let cache = await this.cachePromise;
                return cache.match(`/avatars/${name}.jpg`);
            }
        }
        let storage = new Storage()
        storage.getAvatat('jake').then(
            // ...
        )

        /* 箭头函数 */
        let foo = async () => {}
    </script>
</body>
</html>